// Game.cs
//

using System;
using System.Collections.Generic;
using System.Html;
using System.Html.Media.Graphics;
using Moonbeam.Input;

namespace Moonbeam.Core
{
    public class Game
    {

        SpriteBatch spriteBatch;
        GraphicsDevice graphicsDevice;
        GameTime gameTime;
        InputHandler inputHandler;

        public Game()
        {
            #region create the core GameComponents
            
            GameComponentManager.Instance.AddComponent(new GraphicsDevice("gameCanvas"));
            GameComponentManager.Instance.AddComponent(new SpriteBatch());
            GameComponentManager.Instance.AddComponent(new GameTime(10));
            GameComponentManager.Instance.AddComponent(new InputHandler(Window.Self));

            #endregion

            #region get handy referneces to core game components

            graphicsDevice = (GraphicsDevice)GameComponentManager.Instance.GetComponent(typeof(GraphicsDevice));
            spriteBatch = (SpriteBatch)GameComponentManager.Instance.GetComponent(typeof(SpriteBatch));
            gameTime = (GameTime)GameComponentManager.Instance.GetComponent(typeof(GameTime));
            inputHandler = (InputHandler)GameComponentManager.Instance.GetComponent(typeof(InputHandler));

            #endregion

            Initialise(graphicsDevice);

            //start the mani game loop
            Window.SetInterval(gameLoop, 10);//run 100 times a second, if possible
        }

        private void gameLoop()
        {
            drawStart(spriteBatch, gameTime);
            Draw(spriteBatch, gameTime);
            drawEnd(spriteBatch, gameTime);

            gameTime.Update();

            if (!gameTime.IsRunningSlowly)
            {
                updateSart(gameTime);
                Update(gameTime);
                updateEnd(gameTime);
            }
        }

        private void drawStart(SpriteBatch spriteBatch, GameTime gameTime)
        {
            graphicsDevice.Clear();
        }

        private void drawEnd(SpriteBatch spriteBatch, GameTime gameTime)
        {
        }

        private void updateSart(GameTime gameTime)
        {
            inputHandler.Update();
        }

        private void updateEnd(GameTime gameTime)
        {
        }

        #region virtual methods

        public virtual void Update(GameTime gameTime) { }

        public virtual void Draw(SpriteBatch spriteBatch, GameTime gameTime) { }

        public virtual void Initialise(GraphicsDevice graphiceDevice) { }

        #endregion
    }
}
